package fr.fermat.lyricsext;


import java.util.Timer;
import fr.fermat.control.Controller;
import fr.fermat.databaseManager.LyricManager;
import fr.fermat.databaseManager.Lyrics;
import android.os.Bundle;
import android.os.IBinder;
import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.app.ProgressDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.Display;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.WindowManager;
import android.widget.Toast;
import fr.fermat.network.LyricService;


public class MainActivity extends FragmentActivity implements LyricServiceListener{

	private String trackName;
	private String albumName;
	private String artistName;
	private LyricManager manager;
	private LyricService boundService;
	private Timer timer;
	
	private ViewFragment viewerFragment;
	private EditFragment editorFragment;
	private WebFragment webFragment;
	private ActionBar actionbar;
	private TabsListener tabListener;
	private ProgressDialog pdialog;
	private Lyrics lyric;
	
	private ComponentName aname;
	private IBinder aservice;
	private Intent serviceIntent;
	private Controller controller;
    private boolean mBound = false;
    private String lyricView =""; 
    private Tab tab;

	
	private ServiceConnection serviceConnection = new ServiceConnection() {

		public void onServiceDisconnected(ComponentName name) {
			stopService(serviceIntent);
			mBound = false;

		}
        @Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			Log.d("LyricActivity", "called onServiceConnected");
			boundService = ((LyricService.LocalBinder) service)
					.getService();	
			aname = name;
			aservice = service;
			mBound = true;
			controller.setService(boundService);
		}

	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		Log.d("Activity", "onCreate() called");
		bindService(new Intent(getApplicationContext(),
				               LyricService.class), serviceConnection, Context.BIND_AUTO_CREATE);
       //Get current screen orientation
        Display display =  ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
        int orientation = display.getRotation(); 
         switch(orientation) {
            case Configuration.ORIENTATION_PORTRAIT:
                setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
                break;
            case Configuration.ORIENTATION_LANDSCAPE:
                setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
                break;                   
        }
		  
		
		getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

		// ActionBar gets initiated
		actionbar = getActionBar();
		// Tell the ActionBar we want to use Tabs.
		actionbar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
		// initiating both tabs and set text to it.
		ActionBar.Tab viewerTab = actionbar.newTab().setText(
				getApplicationContext().getString(R.string.tabviewer));
		ActionBar.Tab editTab = actionbar.newTab().setText(
				getApplicationContext().getString(R.string.tabeditor));
		ActionBar.Tab webTab = actionbar.newTab().setText(
				getApplicationContext().getString(R.string.tabweb));

		this.controller = new Controller();

		// create the two fragments we want to use to display content
		viewerFragment = new ViewFragment(this.controller);
		editorFragment = new EditFragment(this.controller);
		webFragment = new WebFragment();
		
		lyricView = viewerFragment.getLyricView();

		tabListener = new TabsListener(new Fragment[] { viewerFragment,
				editorFragment,webFragment});

		// set the Tab listener. Now we can listen for clicks.
		viewerTab.setTabListener(this.tabListener);
		editTab.setTabListener(this.tabListener);
		webTab.setTabListener(this.tabListener);
		
		// add the two tabs to the actionbar
		this.actionbar.addTab(viewerTab);
		this.actionbar.addTab(editTab);
		this.actionbar.addTab(webTab);
		
		this.actionbar.setSelectedNavigationItem(0);
		
		tab = viewerTab;

	}
	

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	 @Override
	    public void onConfigurationChanged(Configuration newConfig) {
	        super.onConfigurationChanged(newConfig);
	 
	        // Checks the orientation of the screen for landscape and portrait
	        if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
	        	//Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
	        	//	setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
	        } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
	        	// Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
	        	//	setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 
	        }
	    }
	 
     	@Override
	protected void onDestroy() {
     		super.onDestroy();
		
	}


	public String getLyricView() {
			return lyricView;
		}


		public void setLyricView(String lyricView) {
			this.lyricView = lyricView;
		}


	@Override
	protected void onPause() {
		super.onPause();
		if (this.actionbar.getSelectedNavigationIndex() == 1) {
			this.actionbar.setSelectedNavigationItem(0);
		}
        Log.d("MainActivity", "onPause() called");
		
		if(this.boundService != null) {
			Log.e("stopService", "stopService");
		} else {
			Log.e("","Service null");
		}
		if(serviceIntent != null) {
			stopService(serviceIntent);
		}
		unbindService(serviceConnection);
	}


	@Override
	protected void onResume() {
		super.onResume();
		Log.d("MainActivity", "resumed");

		serviceIntent = new Intent(getApplicationContext(),
				LyricService.class);
		
		bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE);
			
		if (aname != null && aservice != null && serviceConnection != null) {
			serviceConnection.onServiceConnected(aname, aservice);
		}
		controller.setService(boundService);
		lyricView = controller.getLyricView();
	}
	


		@Override
	protected void onStart() {
		super.onStart();
		Log.d("MainActivity", "start");
		requestserver();
	}


		public String getTrackName() {
		    return trackName;
	    }

	    public String getAlbumName() {
		    return albumName;
	    }

	    public String getArtistName() {
	    	return artistName;
	    }
	    
	    public void setTrackName(String trackName) {
			this.trackName = trackName;
		}

		public void setArtistName(String artistName) {
			this.artistName = artistName;
		}

		public void setAlbumName(String albumName) {
			this.albumName = albumName;
		}
		public EditFragment getEditFragment() {
	    	return editorFragment;
	    }
		public WebFragment getWebFragment() {
	    	return webFragment;
	    }
		public ViewFragment getViewFragment() {
	    	return viewerFragment;
	    }


		/**
		 * Returns the {@link LyricService}
		 * 
		 * @return the {@link LyricService}
		 */
		public LyricService getLyricService() {
			return this.boundService;
		}
		
		private void doBindService() {
		    // Establish a connection with the service.  We use an explicit
		    // class name because we want a specific service implementation that
		    // we know will be running in our own process (and thus won't be
		    // supporting component replacement by other applications).
		    bindService(new Intent(this, 
		            LyricService.class), serviceConnection, Context.BIND_AUTO_CREATE);
		    mBound = true;
		}

		private void doUnbindService() {
		    if (mBound) {
		        // Detach our existing connection.
		        unbindService(serviceConnection);
		        mBound = false;
		    }
		}
		

		
		/**
		 * The TabsListener that registers when the user wants to change to tab
		 */
		public class TabsListener implements ActionBar.TabListener {
			private Fragment fragment[];
			private boolean flag;
			private Tab lastTab;

			public TabsListener(Fragment[] fragment) {
				this.fragment = fragment;
				this.flag = true;
				this.lastTab = null;
			}

			public void onTabReselected(Tab tab, FragmentTransaction ft) {
			}

			/**
			 * switches the tab to the selected one
			 */
			public void onTabSelected(Tab tab, FragmentTransaction ft) {
				// if controller available, change
				flag = false;
				if (tab.getText().equals(
						getApplicationContext().getString(
								R.string.tabviewer))) {


		
					 
				 
		
                 ft = getFragmentManager().beginTransaction();
                 viewerFragment.setLyricView(lyricView);
                 ft.commit();
                 Log.w("TabsListener", "fragment replace");
                 ft.replace(R.id.fragmentContainer,
							fragment[tab.getPosition()]);
                 Log.w("TabsListener", "fragment replace  pruefen");
								 
				} else {
					try {
						Log.w("TabsListener", "fragment replace");
						ft.replace(R.id.fragmentContainer,
								fragment[tab.getPosition()]);
					} catch (IllegalStateException e) {
						Log.d("TabsListener", "Fragment switching crash");
					}
				}
			}

			public void onTabUnselected(Tab tab, FragmentTransaction ft) {
				if (flag) {
					try {
						// ft.remove(fragment[tab.getPosition()]);
					} catch (IllegalStateException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					this.lastTab = tab;
				}
			}

			public void togleFlag() {
				this.flag = !this.flag;
			}
			
			public void onChangehappened(Tab tab, FragmentTransaction ft) {
				this.onTabSelected(tab, ft);
			}

		}
		public Lyrics getLyric() {
			return lyric;
		}


		public void setLyric(Lyrics lyric) {
			this.lyric = lyric;
		}


		/**
		 * Removes the "connecting" dialog when a connection to Ice was possible and
		 * the control fragment could be loaded successfully
		 */
		public void onRequestFinished() {

			tabListener.togleFlag();
			FragmentTransaction ft = this.getFragmentManager().beginTransaction();
			try {
			     pdialog.dismiss();
			     Log.w("MainActivity onRequestFinished", "Dialog dismissed.");
			} catch (NullPointerException np) {
				Log.e("MainActivity", "Dialog schon dismmissed");
			}
			try {
				Log.w("TabsListener", "fragment replace");
				ft.replace(R.id.fragmentContainer, viewerFragment);
			} catch (IllegalStateException e) {
				Log.d("TabsListener", "Fragment switching crash");
	
			}
			ft.commit();
		}
        
		@Override
		public boolean onKeyDown(int keyCode, KeyEvent event) {
			if (actionbar.getSelectedTab().equals(actionbar.getTabAt(2))) {
			// Check if the key event was the Back button and if there's history
		        if(event.getAction() == KeyEvent.ACTION_DOWN)	{
			       if ((keyCode == KeyEvent.KEYCODE_BACK)
				     	&& webFragment.getWebView().canGoBack()) {
			    	   Log.d("Web", "can go back: stay in web"); 
			    	   webFragment.getWebView().goBack();
				        return true;
			       } else {
			    	   Log.d("Web", "can not go back: back to edit");
			    	   actionbar.selectTab(actionbar.getTabAt(1));
			    	   return true;
			       }
		        }	
		    } else if(actionbar.getSelectedTab().equals(actionbar.getTabAt(1))) {
		    	if(event.getAction() == KeyEvent.ACTION_DOWN)	{
				       if (keyCode == KeyEvent.KEYCODE_BACK) {
				    	 Log.d("Edi", "go back: back to view");
				    	 actionbar.selectTab(actionbar.getTabAt(0));
					     return true;
				       }
		    	}
		    }
		    // If it wasn't the Back key or there's no web page history, bubble up to the default
		    // system behavior (probably exit the activity)
		    return super.onKeyDown(keyCode, event);
		}

		public void requestserver() {
			   
	    	try { 
	              if(controller.getLyricView() != null) {
	            	  setLyricView(controller.getLyricView());
	              }
	            } catch (NullPointerException np) {
		             Log.e("controller _lyric", "null"); 
	            } catch (Exception e) {
	            	 Log.e("controller _lyric", "null");
	            }
	   
 final FragmentTransaction ft = this.getFragmentManager().beginTransaction();
 if (lyricView.equals("Sorry, we couldn't find the desired Lyrics!") ||
		 lyricView.equals("No internet Connection")) {
    Log.d("Mainactivity", "LyricView not vide");
	new Thread( new Runnable() {
	   public void run() {
		 if (controller.isConnectingToInternet(getApplicationContext())) {
			 Log.e("MainActivity", "connection ");
			 MainActivity.this.runOnUiThread(new Runnable() {
	               public void run() {	
					pdialog = ProgressDialog.show(MainActivity.this,
							MainActivity.this
									.getString(R.string.requestinglyric),
							MainActivity.this
									.getString(R.string.dialog_progress), false,
							true, new DialogInterface.OnCancelListener() {

								public void onCancel(DialogInterface dialog) {
									actionbar.selectTab(tab);
								}
							});
	                     }
	                  
			     	});
			 while (boundService == null) { }
			 if (boundService != null) {
					Log.d("boundService", "nicht null");
				boolean result;
				timer = new Timer();
				timer.schedule(new ConnectionTask(MainActivity.this,
						pdialog, tab), 10000);
					try {
						
            		     lyricView = boundService.getLyricsFromServer(lyric,
            		    		 (LyricServiceListener)MainActivity.this, MainActivity.this);
            		     result = true;
            	        } catch (NullPointerException e) {
            		        Log.e("Service", "service null");
            		        result = false;
            	        } catch (Exception e) {
            	    	 result = false;
            	        }
					if (result) { 
						controller.setLyricView(lyricView);
						 ft.detach(viewerFragment);
						 ft.attach(viewerFragment);
						 ft.replace(R.id.fragmentContainer, viewerFragment);
		            	 ft.commit();
							
					}
			      }  
              } else {
            	    lyricView = "No internet Connection";
            	    Log.e("MainActivity", "connection error");
            	    controller.setLyricView(lyricView);
            	   
						 ft.detach(viewerFragment);
						 ft.attach(viewerFragment);
					     ft.replace(R.id.fragmentContainer, viewerFragment);
            	         ft.commit();
				
					
              }
	       }
         }).start();
		}
	}  
		 /**
		  * Show a Toast with this Message
		  * @param message
		  * @param activity
		  */
		public static void RunToMe(final String message, final Activity activity) {
			// TODO Auto-generated method stub
			activity.runOnUiThread(new Runnable() {
				public void run() {
					Toast.makeText(activity.getApplicationContext(),message, Toast.LENGTH_LONG).show();
				}
			});
		}
}
